#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

#define T_DIR      1
#define T_FILE     2
#define T_DEVICE   3
#define DIRSIZ 14

struct dirent {
  ushort inum;
  char name[DIRSIZ];
};

// 手动实现 strncmp 函数
int my_strncmp(const char *s1, const char *s2, int n) {
    for (int i = 0; i < n; i++) {
        if (s1[i] != s2[i]) {
            return s1[i] - s2[i];
        }
        if (s1[i] == '\0') {
            return 0;
        }
    }
    return 0;
}

int match(char *name, char *pattern) {
    if (pattern[0] == '*' && pattern[1] == '\0') {
        return 1;
    }

    if (pattern[0] == '*' && pattern[1] != '\0') {
        char *sub = pattern + 1;
        int name_len = strlen(name);
        int sub_len = strlen(sub);
        if (name_len < sub_len) return 0;
        return strcmp(name + name_len - sub_len, sub) == 0;
    }

    if (pattern[strlen(pattern)-1] == '*') {
        int pat_len = strlen(pattern) - 1;
        return my_strncmp(name, pattern, pat_len) == 0;  // 使用自定义的 my_strncmp
    }

    return strcmp(name, pattern) == 0;
}

void findx(char *path, char *pattern) {
    char buf[512], *p;
    int fd;
    struct dirent de;
    struct stat st;

    if ((fd = open(path, 0)) < 0) {
        fprintf(2, "findx: cannot open %s\n", path);
        return;
    }

    if (fstat(fd, &st) < 0) {
        fprintf(2, "findx: cannot stat %s\n", path);
        close(fd);
        return;
    }

    if (st.type != T_DIR) {
        fprintf(2, "findx: %s is not a directory\n", path);
        close(fd);
        return;
    }

    if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {
        fprintf(2, "findx: path too long\n");
        close(fd);
        return;
    }

    strcpy(buf, path);
    p = buf + strlen(buf);
    *p++ = '/';

    while (read(fd, &de, sizeof(de)) == sizeof(de)) {
        if (de.inum == 0)
            continue;

        memmove(p, de.name, DIRSIZ);
        p[DIRSIZ] = 0;

        char *end = p;
        while (end < buf + sizeof(buf) && *end != 0) {
            end++;
        }
        *end = 0;

        if (stat(buf, &st) < 0) {
            fprintf(2, "findx: cannot stat %s\n", buf);
            continue;
        }

        if (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0) {
            continue;
        }

        if (st.type == T_DIR) {
            findx(buf, pattern);
        }

        if (match(de.name, pattern)) {
            printf("%s\n", buf);
        }
    }

    close(fd);
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(2, "Usage: findx <directory> <pattern>\n");
        fprintf(2, "Pattern examples: *.c, test*, file.txt\n");
        exit();
    }

    findx(argv[1], argv[2]);
    exit();
}